/**
 * Created by yanxiaojun617@163.com on 12-27.
 */
// import { Network } from '@ionic-native/network';
import { Injectable } from '@angular/core';
// import { StatusBar } from '@ionic-native/status-bar';
// import { SplashScreen } from '@ionic-native/splash-screen';
// import { AppVersion } from '@ionic-native/app-version';
import { Camera, CameraOptions } from '@ionic-native/camera';
// import { Toast } from '@ionic-native/toast';
import { File, FileEntry } from '@ionic-native/file';
// import { InAppBrowser } from '@ionic-native/in-app-browser';
import { ImagePicker } from '@ionic-native/image-picker';
import { AlertController, Platform } from 'ionic-angular';
// import { AppMinimize } from '@ionic-native/app-minimize';
// import { CallNumber } from '@ionic-native/call-number';
// import { BarcodeScanner } from '@ionic-native/barcode-scanner';
// import { Position } from '../model/type';
import { CODE_PUSH_DEPLOYMENT_KEY, IMAGE_SIZE, IS_DEBUG, QUALITY_SIZE } from './Constants';
import { Observable } from 'rxjs/Rx';
import { Logger } from './Logger';
import { Diagnostic } from '@ionic-native/diagnostic';
// import { CodePush } from '@ionic-native/code-push';

declare var LocationPlugin;
// declare var AMapNavigation;

@Injectable()
export class NativeService {
	// private loading: Loading;

	constructor(
		private platform: Platform,
		// private toastCtrl: ToastController,
		private alertCtrl: AlertController,
		// private statusBar: StatusBar,
		// private splashScreen: SplashScreen,
		//   private appVersion: AppVersion,
		private camera: Camera,
		//   private toast: Toast,
		private file: File,
		//   private inAppBrowser: InAppBrowser,
		private imagePicker: ImagePicker,
		//   private network: Network,
		//   private appMinimize: AppMinimize,
		//   private cn: CallNumber,
		//   private barcodeScanner: BarcodeScanner,
		// private loadingCtrl: LoadingController,
		public logger: Logger,
		private diagnostic: Diagnostic //   private codePush: CodePush
	) {}
	isMobile(): boolean {
		return this.platform.is('mobile') && !this.platform.is('mobileweb');
	}
	getLocation() {
		// alert("1");
		return Observable.create((observer) => {
			// alert('getLocation');
			if (this.isMobile()) {
				alert('getLocation');
				//  检查app是否开始位置服务和定位权限.没有则会请求权限
				Observable.zip(this.assertLocationService(), this.assertLocationAuthorization()).subscribe(
					() => {
						LocationPlugin.getLocation(
							(data) => {
								//  android返回data形如:{"locationType":4,"latitude":23.119225,"longitude":113.350784,"hasAccuracy":true,"accuracy":29,"address":"广东省广州市天河区潭乐街靠近广电科技大厦","country":"中国","province":"广东省","city":"广州市","district":"天河区","street":"平云路","cityCode":"020","adCode":"440106","aoiName":"广电平云广场","speed":0,"bearing":0,"time":1515976535559}
								//  其中locationType为定位来源.定位类型对照表: http://lbs.amap.com/api/android-location-sdk/guide/utilities/location-type/
								//  iOS只会返回data形如:{longitude: 113.35081420800906, latitude: 23.119172707345594}
								console.log('定位信息', data);
								observer.next({ lng: data.longitude, lat: data.latitude });
							},
							(msg) => {
								if (msg.indexOf('缺少定位权限') != -1 || (this.isIos() && msg.indexOf('定位失败') != -1)) {
									this.alertCtrl
										.create({
											title: '缺少定位权限',
											subTitle: '请在手机设置或app权限管理中开启',
											buttons: [
												{ text: '取消' },
												{
													text: '去开启',
													handler: () => {
														this.diagnostic.switchToSettings();
													}
												}
											]
										})
										.present();
								} else if (msg.indexOf('WIFI信息不足') != -1) {
									alert('定位失败,请确保连上WIFI或者关掉WIFI只开流量数据');
								} else if (msg.indexOf('网络连接异常') != -1) {
									alert('网络连接异常,请检查您的网络是否畅通');
								} else {
									alert('获取位置错误,错误消息:' + msg);
									this.logger.log(msg, '获取位置失败');
								}
								observer.error('获取位置失败');
							}
						);
					},
					(err) => {
						observer.error(err);
					}
				);
			} else {
				console.log('非手机环境,即测试环境返回固定坐标');
				observer.next({ lng: 120.69847763, lat: 27.9209616 });
			}
		});
	}
	private assertLocationAuthorization = (() => {
		let locationAuthorization = false;
		return () => {
			return Observable.create((observer) => {
				if (locationAuthorization) {
					observer.next(true);
				} else {
					this.diagnostic
						.isLocationAuthorized()
						.then((res) => {
							if (res) {
								locationAuthorization = true;
								observer.next(true);
							} else {
								locationAuthorization = false;
								this.diagnostic
									.requestLocationAuthorization('always')
									.then((res) => {
										// 请求定位权限
										if (res == 'DENIED_ALWAYS') {
											// 拒绝访问状态,必须手动开启
											locationAuthorization = false;
											this.alertCtrl
												.create({
													title: '缺少定位权限',
													subTitle: '请在手机设置或app权限管理中开启',
													buttons: [
														{ text: '取消' },
														{
															text: '去开启',
															handler: () => {
																this.diagnostic.switchToSettings();
															}
														}
													]
												})
												.present();
											observer.error(false);
										} else {
											locationAuthorization = true;
											observer.next(true);
										}
									})
									.catch((err) => {
										this.logger.log(err, '调用diagnostic.requestLocationAuthorization方法失败');
										observer.error(false);
									});
							}
						})
						.catch((err) => {
							this.logger.log(err, '调用diagnostic.isLocationAvailable方法失败');
							observer.error(false);
						});
				}
			});
		};
	})();
	private assertLocationService = (() => {
		let enabledLocationService = false; // 手机是否开启位置服务
		return () => {
			return Observable.create((observer) => {
				if (enabledLocationService) {
					observer.next(true);
				} else {
					this.diagnostic
						.isLocationEnabled()
						.then((enabled) => {
							if (enabled) {
								enabledLocationService = true;
								observer.next(true);
							} else {
								enabledLocationService = false;
								this.alertCtrl
									.create({
										title: '您未开启位置服务',
										subTitle: '正在获取位置信息',
										buttons: [
											{ text: '取消' },
											{
												text: '去开启',
												handler: () => {
													this.diagnostic.switchToLocationSettings();
												}
											}
										]
									})
									.present();
								observer.error(false);
							}
						})
						.catch((err) => {
							this.logger.log(err, '调用diagnostic.isLocationEnabled方法失败');
							observer.error(false);
						});
				}
			});
		};
	})();
	isIos(): boolean {
		return this.isMobile() && (this.platform.is('ios') || this.platform.is('ipad') || this.platform.is('iphone'));
	}
	/**
   * 获得用户当前坐标信息
   * 5秒内只会返回同一结果
   */
	getUserLocation = (() => {
		let lastTime = null; //  缓存上次获取定位时间
		let lastResult = null; //  缓存上次获取的结果
		return () => {
			return Observable.create((observer) => {
				//  5秒内有获取过定位则不再重复获取
				if (lastTime && new Date().getTime() - lastTime < 5000) {
					if (lastResult) {
						observer.next(lastResult);
					} else {
						//  获取定位是异步,所以这里用定时,直到获取到结果
						const timer = setInterval(() => {
							if (lastResult) {
								clearInterval(timer);
								observer.next(lastResult);
							}
						}, 1000);
					}
				} else {
					lastTime = new Date().getTime(); //  准备获取定位时记录时间
					lastResult = null; //  每次重新获取时,需清空上次结果,以免下次一获取在5秒内直接返回上次结果
					this.getLocation().subscribe(
						(res) => {
							lastTime = new Date().getTime(); //  当获取成功,重置上次获取时间
							lastResult = res;
							observer.next(res);
						},
						() => {
							lastTime = null;
						}
					);
				}
			});
		};
	})();
	getPicture(options: CameraOptions = {}): Observable<string> {
		const ops: CameraOptions = {
			sourceType: this.camera.PictureSourceType.CAMERA, // 图片来源,CAMERA:拍照,PHOTOLIBRARY:相册
			destinationType: this.camera.DestinationType.FILE_URI, // 默认返回图片路径：DATA_URL:base64字符串，FILE_URI:图片路径
			quality: QUALITY_SIZE, // 图像质量，范围为0 - 100
			allowEdit: false, // 选择图片前是否允许编辑
			encodingType: this.camera.EncodingType.JPEG,
			targetWidth: IMAGE_SIZE, // 缩放图像的宽度（像素）
			targetHeight: IMAGE_SIZE, // 缩放图像的高度（像素）
			saveToPhotoAlbum: false, // 是否保存到相册
			correctOrientation: true,
			...options
		};
		return Observable.create((observer) => {
			this.camera
				.getPicture(ops)
				.then((imgData: string) => {
					if (ops.destinationType === this.camera.DestinationType.DATA_URL) {
						observer.next('data:image/jpg;base64,' + imgData);
					} else {
						observer.next(imgData);
					}
				})
				.catch((err) => {
					if (err == 20) {
						this.alert('没有权限,请在设置中开启权限');
					} else if (String(err).indexOf('cancel') != -1) {
						console.log('用户点击了取消按钮');
					} else {
						this.logger.log(err, '使用cordova-plugin-camera获取照片失败');
						this.alert('获取照片失败');
					}
					observer.error(false);
				});
		});
	}

	/**
	   * 通过图库选择多图
	   * @param options
	   */
	getMultiplePicture(options = {}): Observable<any> {
		const that = this;
		const ops = {
			maximumImagesCount: 6,
			width: IMAGE_SIZE, // 缩放图像的宽度（像素）
			height: IMAGE_SIZE, // 缩放图像的高度（像素）
			quality: QUALITY_SIZE,
			...options
		};
		return Observable.create((observer) => {
			this.imagePicker
				.getPictures(ops)
				.then((files) => {
					const destinationType = options['destinationType'] || 0; // 0:base64字符串,1:图片url
					if (destinationType === 1) {
						observer.next(files);
					} else {
						const imgBase64s = []; // base64字符串数组
						for (const fileUrl of files) {
							that.convertImgToBase64(fileUrl).subscribe((base64) => {
								imgBase64s.push(base64);
								if (imgBase64s.length === files.length) {
									observer.next(imgBase64s);
								}
							});
						}
					}
				})
				.catch((err) => {
					this.logger.log(err, '通过图库选择多图失败');
					this.alert('获取照片失败');
					observer.error(false);
				});
		});
	}

	/**
	   * 根据图片绝对路径转化为base64字符串
	   * @param path 绝对路径
	   */
	convertImgToBase64(path: string): Observable<string> {
		return Observable.create((observer) => {
			this.file
				.resolveLocalFilesystemUrl(path)
				.then((fileEnter: FileEntry) => {
					fileEnter.file((file) => {
						const reader = new FileReader();
						reader.onloadend = function(e) {
							observer.next(this.result);
						};
						reader.readAsDataURL(file);
					});
				})
				.catch((err) => {
					this.logger.log(err, '根据图片绝对路径转化为base64字符串失败');
					observer.error(false);
				});
		});
	}
	alert = (() => {
		let isExist = false;
		return (title: string, subTitle = '', message = '', callBackFun = null): void => {
			if (!isExist) {
				isExist = true;
				this.alertCtrl
					.create({
						title,
						subTitle,
						message,
						cssClass: 'alert-zIndex-highest',
						buttons: [
							{
								text: '确定',
								handler: () => {
									isExist = false;
									callBackFun && callBackFun();
								}
							}
						],
						enableBackdropDismiss: false
					})
					.present();
			}
		};
	})();
}
